﻿using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using WcfBetterPlace;

namespace StandaloneHost
{
    internal class Program
    {
        /// <summary>
        /// Defines the entry point of the application that is used for starting a host service.
        /// </summary>
        private static void Main()
        {
            //REMEMBER TO RUN VS AS ADMINISTRATOR!
            // Stores all hosts
            List<ServiceHost> hosts = new List<ServiceHost>();

            try
            {
                var servicehosts = new List<WcfAbc>
                {
                    new WcfAbc
                    {
                        TypeOfService = typeof (BetterAdminService),
                        Address = new Uri("http://localhost:8080/BetterAdminService/"),
                        Binding = new BasicHttpBinding(),
                        Contract = typeof (IBetterAdminService)
                    }
                    ,
                    new WcfAbc
                    {
                        TypeOfService = typeof (BetterAdminService),
                        Address = new Uri("http://localhost:8081/BetterAdminService/"),
                        Binding = new WSHttpBinding(),
                        Contract = typeof (IBetterAdminService)
                    },
                    new WcfAbc
                    {
                        TypeOfService = typeof (BetterAdminService),
                        Address = new Uri("net.tcp://localhost:8082/BetterAdminService/"),
                        Binding = new NetTcpBinding(),
                        Contract = typeof (IBetterAdminService)
                    },
                    new WcfAbc
                    {
                        TypeOfService = typeof (BetterClientService),
                        Address = new Uri("http://localhost:8081/BetterClientService/"),
                        Binding = new WSHttpBinding(),
                        Contract = typeof (IBetterClientService)
                    }
                };
                foreach (var service in servicehosts)
                {
                    var host = new ServiceHost(service.TypeOfService);
                    host.AddServiceEndpoint(service.Contract, service.Binding, service.Address);
                    if (service.Binding.GetType() != typeof(NetTcpBinding))
                    {
                        ServiceMetadataBehavior smb = new ServiceMetadataBehavior
                        {
                            HttpGetEnabled = true,
                            HttpsGetEnabled = true,
                            HttpGetUrl = service.Address,
                            MetadataExporter = { PolicyVersion = PolicyVersion.Policy15 }
                        };
                        host.Description.Behaviors.Add(smb);
                    }

                    hosts.Add(host);  // Add to the host collection
                    host.Open();      // Open the host

                    Console.WriteLine("The service {0} is ready at:", service.TypeOfService);
                    ServiceDescription desc = host.Description;
                    foreach (ServiceEndpoint endpoint in desc.Endpoints)
                    {
                        Console.WriteLine("Endpoint - address:  {0}", endpoint.Address);
                        Console.WriteLine("           binding:  {0}", endpoint.Binding.Name);
                        Console.WriteLine("           contract: {0}", endpoint.Contract.Name);
                        Console.WriteLine();
                    }
                }
                Console.WriteLine("\nPress <Enter> to close down.");
                Console.ReadLine();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.ReadLine();
            }
            finally
            {
                foreach (ServiceHost host in hosts)
                {
                    if (host.State == CommunicationState.Opened)
                    {
                        host.Abort();
                        host.Close();
                    }
                    else
                    {
                        host.Close();
                    }
                }
            }
        }

        private class WcfAbc
        {
            public Type TypeOfService { get; set; }

            public Uri Address { get; set; }

            public Binding Binding { get; set; }

            public Type Contract { get; set; }
        }
    }
}